package codec

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"my-gameserver-go/logic/structs"
	"net"
)

type TcpCoder struct {
	HeadLen int
}

//Decode 如果拆包错误,则链接断开
func (coder *TcpCoder) Decode(conn *net.TCPConn) (structs.ReqMessage, bool) {
	var msg structs.ReqMessage
	headData := make([]byte, coder.HeadLen)
	_, err := io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
	if err != nil {
		fmt.Printf("read headData error %s", err)
		return msg, false
	}
	reader := bytes.NewReader(headData)
	if err := binary.Read(reader, binary.LittleEndian, &msg.DataLen); err != nil {
		fmt.Printf("read datalen err %s", err)
		return msg, false
	}
	if err := binary.Read(reader, binary.LittleEndian, &msg.ID); err != nil {
		fmt.Printf("read msgId error %s", err)
		return msg, false
	}

	if msg.DataLen > 0 {
		//切片
		msg.Data = make([]byte, msg.DataLen)
		_, err := io.ReadFull(conn, msg.Data) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Printf("read msgData error %s", err)
			return msg, false
		}
	}
	return msg, true
}

func (coder *TcpCoder) Codec(message structs.ResMessage) ([]byte, error) {

	dataBuff := bytes.NewBuffer([]byte{})
	//写msgLen
	if err := binary.Write(dataBuff, binary.LittleEndian, message.GetMsgLen()); err != nil {
		return nil, err
	}
	//写msgID
	if err := binary.Write(dataBuff, binary.LittleEndian, message.MsgId); err != nil {
		return nil, err
	}
	//写状态码
	if err := binary.Write(dataBuff, binary.LittleEndian, message.ResCode); err != nil {
		return nil, err
	}
	//写data数据
	if err := binary.Write(dataBuff, binary.LittleEndian, message.ProtoData); err != nil {
		return nil, err
	}

	return dataBuff.Bytes(), nil
}
